﻿using Microsoft.EntityFrameworkCore;
using OL.FrameCore.Application.SysLog.Dto;
using OL.FrameCore.Domain.Entity;
using OL.FrameCore.Infrastructure.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace OL.FrameCore.Application.SysLog
{
    public class SysLogService: ISysLogService
    {
        IUnitOfWork _unitOfwork;
        public SysLogService(IUnitOfWork unitOfwork)
        {
            _unitOfwork = unitOfwork;
        }

        /// <summary>
        /// 获取用户操作日志列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public PageData<GetUserOperateLogListResponse> GetUserOperateLogList(GetUserOperateLogListRequest request)
        {
            var repositoryUserOperateLog = _unitOfwork.GetRepository<SysUserOperateLog>();
            var repositoryUser = _unitOfwork.GetRepository<SysUser>();

            //Expression<Func<SysUserOperateLog, bool>> predicate = p =>
            //(request.OperateId.HasValue == false ? true : p.OperateId == request.OperateId)
            //&& (request.OperateType.HasValue == false ? true : p.OperateType == request.OperateType)
            //&& (request.UserId.HasValue == false ? true : p.UserId == request.UserId);
            //var query = repositoryUserOperateLog.TableNoTracking.Where(predicate).Select(p => new GetUserOperateLogListResponse
            //{
            //    Id = p.Id,
            //    UserId = p.UserId,
            //    OperateType = p.OperateType,
            //    Remark = p.Remark,
            //    IP = p.IP,
            //    OperateId = p.OperateId,
            //    CreateTime = p.CreateTime
            //});

            var query = from a in repositoryUserOperateLog.TableNoTracking
                        join b in repositoryUser.TableNoTracking on a.UserId equals b.Id
                        join c in repositoryUser.TableNoTracking on a.OperateId equals c.Id
                        where (request.OperateId.HasValue == false ? true : a.OperateId == request.OperateId)
                        && (request.OperateType.HasValue == false ? true : a.OperateType == request.OperateType)
                        && (request.UserId.HasValue == false ? true : a.UserId == request.UserId)
                        && a.CreateTime >= request.BeginTime
                        && a.CreateTime < request.EndTime.AddDays(1)
                        orderby a.CreateTime descending
                        select new GetUserOperateLogListResponse
                        {
                            Id = a.Id,
                            UserId = a.UserId,
                            UserName = b.TrueName,
                            OperateType = a.OperateType,
                            Remark = a.Remark,
                            OperateId = a.OperateId,
                            OperateName = c.TrueName,
                            IP = a.IP,
                            CreateTime = a.CreateTime
                        };


            return repositoryUserOperateLog.PagingAsync<GetUserOperateLogListResponse>(query, request.PageIndex, request.PageSize).Result;
        }

        /// <summary>
        /// 获取系统错误日志列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public PageData<GetErrorLogListResponse> GetErrorLogList(GetErrorLogListRequest request)
        {
            var repositoryErrorLog = _unitOfwork.GetRepository<SysErrorLog>();
            var query = from a in repositoryErrorLog.TableNoTracking
                        where (string.IsNullOrEmpty(request.IP) ? true : a.IP == request.IP)
                        && (string.IsNullOrEmpty(request.UserId) ? true : a.UserId == request.UserId)
                        && (string.IsNullOrEmpty(request.ErrorInfo) ? true : a.ErrorInfo.Contains(request.ErrorInfo))
                        && a.CreateTime >= request.BeginTime
                        && a.CreateTime < request.EndTime.AddDays(1)
                        select new GetErrorLogListResponse
                        {
                            Id = a.Id,
                            UserId = a.UserId,
                            IP = a.IP,
                            ErrorInfo = a.ErrorInfo,
                            CreateTime = a.CreateTime
                        };

            return repositoryErrorLog.PagingAsync<GetErrorLogListResponse>(query, request.PageIndex, request.PageSize).Result;
        }

        /// <summary>
        /// 获取用户登录日志列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public PageData<GetUserLoginLogListResponse> GetUserLoginLogList(GetUserLoginLogListRequest request)
        {
            var repositoryUserLoginLog = _unitOfwork.GetRepository<SysUserLoginLog>();
            var query = from a in repositoryUserLoginLog.TableNoTracking
                        where (string.IsNullOrEmpty(request.UserName) ? true : a.UserName == request.UserName)
                        && (string.IsNullOrEmpty(request.IP) ? true : a.IP == request.IP)
                        && (request.LoginStatus.HasValue == false ? true : a.LoginStatus == request.LoginStatus)
                        && (request.UserId.HasValue == false ? true : a.UserId == request.UserId)
                        && a.LoginTime >= request.BeginTime
                        && a.LoginTime < request.EndTime.AddDays(1)
                        orderby a.LoginTime descending
                        select new GetUserLoginLogListResponse
                        {
                            Id = a.Id,
                            UserName = a.UserName,
                            UserId = a.UserId,
                            IP = a.IP,
                            UserAgent = a.UserAgent,
                            LoginStatus = a.LoginStatus,
                            LoginTime = a.LoginTime
                        };

            return repositoryUserLoginLog.PagingAsync<GetUserLoginLogListResponse>(query, request.PageIndex, request.PageSize).Result;
        }

        /// <summary>
        /// 记录错误日志
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public Result LogError(LogErrorRequest request)
        {
            var repositoryErrorLog = _unitOfwork.GetRepository<SysErrorLog>();
            repositoryErrorLog.Insert(new SysErrorLog
            {
                ErrorInfo = request.ErrorInfo,
                IP = request.IP,
                UserId = request.UserId,
                CreateTime = request.CreateTime
            });
            _unitOfwork.Save();

            return new SuccessResult();
        }
    }
}
